Skip to content

Remove some occurrences of too-many-branches code smells#836

Open
rlimapro wants to merge 7 commits into
redis:mainfrom
renansuaris:rian-lima/refactor/too-many-branches
Open

Remove some occurrences of too-many-branches code smells#836
rlimapro wants to merge 7 commits into
redis:mainfrom
renansuaris:rian-lima/refactor/too-many-branches

Conversation

@rlimapro
Copy link
Copy Markdown

@rlimapro rlimapro commented May 31, 2026

Note

Medium Risk
Large, behavior-preserving refactor across query execution, serialization, schema generation, and migrations; risk is regression in edge cases despite added tests, not security.

Overview
This PR refactors high-branch code across the library by splitting large functions into smaller helpers, without changing the intended public behavior. The goal is to satisfy static-analysis “too many branches” rules and make complex paths easier to maintain.

Serialization and encoding: jsonable_encoder in encoders.py is decomposed into typed helpers (Pydantic models, dicts, iterables, custom/builtin encoders, fallback). New tests cover nested types, custom encoders, and vars() fallback.

Model core (model.py): Timestamp/base64 conversion, FindQuery (internal _FindQueryState / _FindQueryCache, query building, JSON path projection, execute pipeline), RediSearch resolve_value, deep-field validation, ModelMeta.__new__, HashModel.save (TTL preservation), JsonModel/HashModel schema builders, FieldInfo / VectorFieldOptions (optional params grouped in VectorFieldParameters), and related pieces are broken into focused functions. DefaultMeta switches from a dataclass to class-level ClassVar defaults.

Migrations: Datetime hash migration logic moves into _collect_hash_keys, _process_hash_batch, _process_hash_key, etc., and drops redundant enable_resume / _processed_keys tracking. Data and schema migrators gain helpers for running migrations, monitoring results, connection recovery, and rollback.

Other: render_tree and RedisVL field mapping use small helpers; legacy_migrator.detect_migrations is simplified similarly.

Tests added or extended for encoders, deep field paths, JSON path projection, render tree layout, timestamp conversion, and RedisVL schema field types.

Reviewed by Cursor Bugbot for commit 3e2a085. Bugbot is set up for automated code reviews on this repo. Configure here.

@jit-ci
Copy link
Copy Markdown

jit-ci Bot commented May 31, 2026

Hi, I’m Jit, a friendly security platform designed to help developers build secure applications from day zero with an MVS (Minimal viable security) mindset.

In case there are security findings, they will be communicated to you as a comment inside the PR.

Hope you’ll enjoy using Jit.

Questions? Comments? Want to learn more? Get in touch with us.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 3e2a085. Configure here.


encoded_obj = _apply_builtin_encoder(obj)
if encoded_obj is not None:
return encoded_obj
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Encoders returning None are silently dropped

Medium Severity

_apply_custom_encoder and _apply_builtin_encoder both return None as a "not found" sentinel, but None is also a valid encoder return value. The if encoded_obj is not None checks in jsonable_encoder cause the code to incorrectly skip an encoder that legitimately returns None and fall through to _encode_fallback_object, which will likely raise a ValueError. The original code returned the encoder's result directly without any None check.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3e2a085. Configure here.

Comment thread aredis_om/redisvl.py
if inner_types and inner_types[0] is str:
attrs = {"sortable": sortable}
return {"name": field_name, "type": "tag", "attrs": attrs}
return _get_container_field_def(field_name, field_type, field_info)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Container fields with non-string types silently excluded from schema

Medium Severity

_get_container_field_def returns None when the container's inner type isn't str, and _get_field_type returns that None directly instead of falling through to the default TAG field. In the original code, container types with non-string inner types would fall through to return {"name": field_name, "type": "tag"}. Now they are silently excluded from the RedisVL schema.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3e2a085. Configure here.

)

applied_count = 0
applied_count, errors = await self._run_pending_migrations_with_monitoring(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead store: applied_count immediately overwritten

Low Severity

applied_count = 0 on line 347 is immediately overwritten by the tuple unpacking on line 348 (applied_count, errors = await self._run_pending_migrations_with_monitoring(...)). The initial assignment is a dead store and serves no purpose.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3e2a085. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants